#include "DesplazadorFichas.h"
#include "DesaparecedorFicha.h"
#include "Mutex.h"
#include <iostream>
#include <gtkmm.h>
#include "VistaFichaTablero.h"
#include "VistaButton.h"
#include "VistaMiniBar.h"
#include "VistaGoldenStar.h"
#include <list>

DesplazadorFichas::DesplazadorFichas(std::list<Json::Value> *tableros,
                                     VistaEscenario *vista,
                                     Mutex *protectorFichas, bool valido) {
    this->vista = vista;
    this->tableros = tableros;
    this->mu = protectorFichas;
    this->valido = valido;
    this->desaparecedor=NULL;
}

void DesplazadorFichas::animacionValida() {

    Json::Value movimiento = tableros->front();
    tableros->pop_front();

    int x1 = movimiento["x1"].asInt();
    int y1 = movimiento["y1"].asInt();
    int x2 = movimiento["x2"].asInt();
    int y2 = movimiento["y2"].asInt();

    Juego::reproductorWav.reproducir(SON_MOVIMIENTO);

    obtenerOrientacion(x1, y1, x2, y2);

    for (int i = 0; i < 53; i++) {
        if (i % 2 == 0) {
            mu->lock();

            if (desplazamientoHorizontal) {
                if (desplazamientoPositivo) {
                    vista->vistaFichas[x1][y1]->yDesde += 2;
                    vista->vistaFichas[x2][y2]->yDesde -= 2;
                } else {
                    vista->vistaFichas[x1][y1]->yDesde -= 2;
                    vista->vistaFichas[x2][y2]->yDesde += 2;
                }
            } else {
                if (desplazamientoPositivo) {
                    vista->vistaFichas[x1][y1]->xDesde += 2;
                    vista->vistaFichas[x2][y2]->xDesde -= 2;
                } else {
                    vista->vistaFichas[x1][y1]->xDesde -= 2;
                    vista->vistaFichas[x2][y2]->xDesde += 2;
                }
            }
            mu->unlock();
        }
        usleep(TIEMPO_DE_REFRESCO*1000);
    }
    /* Se intercambian fichas */
    mu->lock();
    VistaFichaTablero *aux = vista->vistaFichas[x1][y1];
    vista->vistaFichas[x1][y1] = vista->vistaFichas[x2][y2];
    vista->vistaFichas[x2][y2] = aux;
    mu->unlock();

    this->desaparecedor = new DesaparecedorFicha(tableros, vista, mu);
    desaparecedor->start();

    desaparecedor->join();    
}

void DesplazadorFichas::animacionInvalida() {
    
    Json::Value movimiento = tableros->front();
    tableros->pop_front();

    int x1 = movimiento["x1"].asInt();
    int y1 = movimiento["y1"].asInt();
    int x2 = movimiento["x2"].asInt();
    int y2 = movimiento["y2"].asInt();

    obtenerOrientacion(x1, y1, x2, y2);

    Juego::reproductorWav.reproducir(SON_ERROR);

    for (int i = 0; i < 28; i++) {
        mu->lock();
        if (desplazamientoHorizontal) {
            if (desplazamientoPositivo) {
                vista->vistaFichas[x1][y1]->yDesde += 1;
                vista->vistaFichas[x2][y2]->yDesde -= 1;
            } else {
                vista->vistaFichas[x1][y1]->yDesde -= 1;
                vista->vistaFichas[x2][y2]->yDesde += 1;
            }
        } else {
            if (desplazamientoPositivo) {
                vista->vistaFichas[x1][y1]->xDesde += 1;
                vista->vistaFichas[x2][y2]->xDesde -= 1;
            } else {
                vista->vistaFichas[x1][y1]->xDesde -= 1;
                vista->vistaFichas[x2][y2]->xDesde += 1;
            }
        }
        mu->unlock();
        usleep(TIEMPO_DE_REFRESCO*1000);
    }

    for (int i = 0; i < 28; i++) {
        mu->lock();
        if (desplazamientoHorizontal) {
            if (desplazamientoPositivo) {
                vista->vistaFichas[x1][y1]->yDesde -= 1;
                vista->vistaFichas[x2][y2]->yDesde += 1;
            } else {
                vista->vistaFichas[x1][y1]->yDesde += 1;
                vista->vistaFichas[x2][y2]->yDesde -= 1;
            }
        } else {
            if (desplazamientoPositivo) {
                vista->vistaFichas[x1][y1]->xDesde -= 1;
                vista->vistaFichas[x2][y2]->xDesde += 1;
            } else {
                vista->vistaFichas[x1][y1]->xDesde += 1;
                vista->vistaFichas[x2][y2]->xDesde -= 1;
            }
        }
        mu->unlock();

        usleep(TIEMPO_DE_REFRESCO*1000);
    }

    delete this->tableros;
    this->tableros=NULL;
    
    

}

void DesplazadorFichas::obtenerOrientacion(int x1, int y1, int x2, int y2) {
    if (x1 == x2) {
        desplazamientoHorizontal = true;
    } else {
        desplazamientoHorizontal = false;
    }

    if (desplazamientoHorizontal) {
        if (y1 < y2) {
            desplazamientoPositivo = true;
        } else {
            desplazamientoPositivo = false;
        }

    } else {
        if (x1 < x2) {
            desplazamientoPositivo = true;
        } else {
            desplazamientoPositivo = false;
        }
    }
}

void *DesplazadorFichas::run() {
    Partida::setAnimando(true);
    
    if (valido)
        animacionValida();
    else 
        animacionInvalida();
    
    Partida::mostrarMensaje("Puede mover!");
    Partida::setAnimando(false);
    this->exit();
return NULL;
}


DesplazadorFichas::~DesplazadorFichas() {
    if (this->desaparecedor!=NULL){
        Log::loguear(MDEBUG,"Liberando desaparecedor de fichas (1/4)...");
        delete this->desaparecedor;
        this->desaparecedor=NULL;
    }

    /* Libero animaciones parseadas */
    if (this->tableros!=NULL){
        Log::loguear(MDEBUG,"Liberando animaciones parseadas...");
        delete tableros;
        tableros=NULL;
    }
}
